package com.mtcarpenter.stream;

import com.mtcarpenter.common.Fruit;
import com.mtcarpenter.common.FruitDataTest;
import org.junit.Test;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: mtcarpenter
 * @describe
 * @Date: 2019/10/9
 * @Version 1.0
 */
public class QuestionTest {

    /**
     * 1.查询所有价格（price）大于 20 的水果名，结果返回为一个list,并将结果打印显示
     */
    @Test
    public void test01() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        List<String> list = fruites.stream().filter(s -> s.getPrice() > 20).map(Fruit::getName).collect(Collectors.toList());
        System.out.println("价格（price）大于 20 的水果名:");
        list.forEach(System.out::println);
    }

    /**
     * 2.取出水果列表中排列 3，4，5 的水果，并将结果打印显示
     */
    @Test
    public void test02() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        System.out.println("水果中 3，4，5 的水果:");
        fruites.stream().skip(2).limit(3).forEach(System.out::println);
    }

    /**
     * 3.取出水果列表中，水果价格最高的水果名字，并将结果打印显示
     */
    @Test
    public void test03() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        System.out.println("水果价格最高的水果:");
        // 优化前
        fruites.stream().max(((o1, o2) -> Double.compare(o1.getPrice(), o2.getPrice()))).map(Fruit::getName);
        // 优化后
        Optional<String> optional = fruites.stream().max((Comparator.comparingDouble(Fruit::getPrice))).map(Fruit::getName);
        System.out.println(optional.get());
    }

    /**
     * 4.取出水果列表中，水果价格最低的水果名字，并将结果打印显示
     */
    @Test
    public void test04() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        System.out.println("水果价格最低的水果:");
        Optional<String> optional = fruites.stream().min((Comparator.comparingDouble(Fruit::getPrice))).map(Fruit::getName);
        System.out.println(optional.get());
    }

    /**
     * 5.取出水果列表 type 为 2 的水果价格总和,并将结果打印显示
     */
    @Test
    public void test05() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        Optional<Double> optional = fruites.stream().filter(s -> s.getType() == 2).map(Fruit::getPrice).reduce(Double::sum);
        System.out.println("水果 type 为 2 的水果价格总和：" + optional.get());
    }

    /**
     * 6.根据水果列表中 type 进行分类,结果返回为一个 list,并将结果打印显示
     */
    @Test
    public void test06() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        Map<Integer, List<Fruit>> listMap = fruites.stream().collect(Collectors.groupingBy(Fruit::getType, Collectors.toList()));
        listMap.forEach((key, fruits) -> System.out.println(key + "----" + fruits));
    }

    /**
     * 7.根据水果列表进行价格降序，取出前 3 的水果名，结果返回一个 list ，并将结果打印显示
     */
    @Test
    public void test07() {
        List<Fruit> fruites = FruitDataTest.getFruites();
        List<String> result = fruites.stream().sorted((o1, o2) -> Double.compare(o2.getPrice(), o1.getPrice()))
                .map(Fruit::getName).limit(3).collect(Collectors.toList());
        System.out.println("前 3 的水果名为: " + result);
    }

    /**
     * 8.求出水果列表每一个分类（type）下水果的数量总和（num）
     */
    @Test
    public void test08(){
        List<Fruit> fruites = FruitDataTest.getFruites();
        Map<Integer, Integer> result = fruites.stream().collect(Collectors.groupingBy(Fruit::getType,
                Collectors.summingInt(Fruit::getNum)));
        result.forEach((k,v)->{
            System.out.println("分类为："+k+"---"+v);
        });
    }

}
